/**
 * Copyright 2007-2008 Vidar Svansson
 *
 * This file is part of JAdapter.
 *
 * JAdapter is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * JAdapter is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with JAdapter.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.jadapter.zcml;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.List;


import org.jadapter.AdapterFactory;
import org.jadapter.JAdapter;
import org.jadapter.beans.ComponentBean;
import org.jadapter.registry.AdapterRegistry;
import org.jadapter.registry.ComponentRegistry;
import org.jadapter.registry.Components;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
import com.thoughtworks.xstream.io.xml.DomDriver;
/** Experimental support for a <em>subset</em> of 
 * the Zope Configuration markup language, ZCML.
 * 
 * @author Vidar Svansson
 * 
 * @since 0.1
 *
 */
@XStreamAlias("zcml")
public class ZCML {
    
    private static XStream xstream;
    
    @XStreamImplicit
    private List<ComponentBean<?,?>> directives;
    
    public ZCML(){
        directives = new LinkedList<ComponentBean<?,?>>();
    }
    
    public ZCML(InputStream zcml){
        directives = parse(zcml).directives;       
    }
    
    public ZCML(File file) throws FileNotFoundException {
        directives = parse(new FileInputStream(file)).directives;        
    }
    
    
    public static ZCML parse(InputStream zcml) {    
          return (ZCML)getXStream().fromXML(zcml);              
    }
    
    public void addDirective(ComponentBean<?,?> directive) {
        directives.add(directive);
    }
    
    public static void process(InputStream zcml) {
        parse(zcml).process();
    }
    
    public static void process(File file) throws FileNotFoundException {
        process(new FileInputStream(file));
    }
    
    
    public void process() {
    	process(Components.getComponentRegistry());
    }
    
    public void process(ComponentRegistry registry){
        for (ComponentBean<?,?> comp: directives)
            registry.register(comp);    	
    }
    
    public void process(AdapterRegistry registry){
        for (ComponentBean<?,?> comp: directives){
            if(comp instanceof AdapterFactory)
                registry.register((AdapterFactory)comp);        
        }
    }
    
    public static XStream getXStream(){
        if(xstream == null){
            xstream = new XStream(new DomDriver());
            // TODO use proper driver
            xstream.alias("zcml", ZCML.class);
            xstream.addImplicitCollection(ZCML.class, "directives");
            xstream.alias("adapter", JAdapter.class);
            xstream.aliasField("for", JAdapter.class, "context");
            xstream.aliasField("factory", JAdapter.class, "adapterClass");
        }
        return xstream;
    }

}
